package handler

import (
	"boy-go/middlewares"
	"boy-go/modules/system/model"
	"boy-go/modules/system/service"
	"boy-go/modules/system/vo"
	"boy-go/pkg/request"
	"boy-go/pkg/response"
	"boy-go/pkg/security"
	"boy-go/pkg/xexcel"
	"boy-go/pkg/xnum"
	"boy-go/pkg/xstr"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"strings"
)

// AddSysUserRouter 添加路由
func AddSysUserRouter(group *gin.RouterGroup) {
	group.GET("/user/:id", middlewares.HasPermission("system:user:query"), get_user)                                                              // 获取用户信息表详情
	group.GET("/user/", middlewares.HasPermission("system:user:query"), get_user)                                                                 // 获取用户信息表详情
	group.GET("/user/list", middlewares.HasPermission("system:user:list"), list_user)                                                             // 获取用户信息表列表（管理页面）
	group.GET("/user/deptTree", middlewares.HasPermission("system:user:list"), deptTree_user)                                                     // 获取部门下拉树结构
	group.GET("/user/authRole/:id", middlewares.HasPermission("system:user:query"), auth_role_user)                                               // 根据用户编号获取授权角色
	group.PUT("/user/authRole", middlewares.HasPermission("system:user:edit"), middlewares.Logger("用户管理", middlewares.GRANT), add_auth_role_user) // 用户授权角色
	group.POST("/user", middlewares.HasPermission("system:user:add"), middlewares.Logger("用户管理", middlewares.INSERT), add_user)                   // 新增用户信息表
	group.PUT("/user", middlewares.HasPermission("system:user:edit"), middlewares.Logger("用户管理", middlewares.UPDATE), edit_user)                  // 修改用户信息表
	group.DELETE("/user/:ids", middlewares.HasPermission("system:user:remove"), middlewares.Logger("用户管理", middlewares.DELETE), delete_user)      // 删除用户信息表
	group.POST("/user/export", middlewares.HasPermission("system:user:export"), middlewares.Logger("用户管理", middlewares.EXPORT), export_user)
	group.PUT("/user/resetPwd", middlewares.HasPermission("system:user:resetPwd"), middlewares.Logger("用户管理", middlewares.UPDATE), reset_pwd_user)     // 重置密码
	group.PUT("/user/changeStatus", middlewares.HasPermission("system:user:edit"), middlewares.Logger("用户管理", middlewares.UPDATE), change_status_user) // 重置密码
}

// get_user
// @Summary 获取用户信息表详情
// @Description 获取用户信息表详情（管理页面）
// @Tags system-user
// @Accept json
// @Produce json
// @Param id path string true "ID"
// @Success 200 {object} response.R[vo.SysUserModel] "ok"
// @Failure 400 {string} string "bad request"
// @Failure 500 {string} string "Internal Server Error"
// @Router /system/user/{id} [get]
func get_user(ctx *gin.Context) {
	var idStr = ctx.Param("id")
	ajax := response.NewAjaxResultSuccess()
	id := xnum.Str2int64(idStr)
	if idStr != "" {
		m, err := service.NewSysUserService().SelectById(id)
		if err != nil {
			response.AjaxError(ctx, err)
			return
		}
		ajax.SetData(m)
		ajax.Put("roleIds", m.RoleIds)
		ajax.Put("postIds", service.NewSysPostService().SelectPostListByUserId(id))
	}
	roleList := service.NewSysRoleService().SelectRoleAll()
	roles := make([]*vo.SysRoleModel, 0)
	if !model.IsAdmin(&id) {
		for _, roleModel := range roleList {
			if roleModel.RoleId != 1 {
				roles = append(roles, roleModel)
			}
		}
	} else {
		roles = roleList
	}
	ajax.Put("roles", roles)
	ajax.Put("posts", service.NewSysPostService().SelectPostAll())
	response.AjaxResponse(ctx, ajax)
}

// list_user
// @Summary 获取用户信息表列表
// @Description 获取用户信息表列表（管理页面）
// @Tags system-user
// @Accept json
// @Produce json
// @Success 200 {object} response.R[PageRes[vo.SysUserModel]] "ok"
// @Failure 400 {string} string "bad request"
// @Failure 500 {string} string "Internal Server Error"
// @Router /system/user/list [get]
func list_user(ctx *gin.Context) {
	req := vo.QuerySysUserReq{}
	if err := ctx.BindQuery(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	req.Params = request.BindFormParams(ctx)
	pageReq := &request.PageRequest{
		PageNum:  req.PageNum,
		PageSize: req.PageSize,
	}
	page, err := service.NewSysUserService().SelectUserList(&req, pageReq)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	response.AjaxDataTable(ctx, page.List, page.Total)
}

// add
// @Summary 新增用户信息表
// @Description 新增用户信息表（管理页面）
// @Tags system-user
// @Accept json
// @Produce json
// @Param req body  vo.AddSysUserReq true "req"
// @Success 200 {object} response.R[vo.AddSysUserRsp] "ok"
// @Failure 400 {string} string "bad request"
// @Failure 500 {string} string "Internal Server Error"
// @Router /system/user [post]
func add_user(ctx *gin.Context) {
	var req vo.AddSysUserReq
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err := service.NewSysDeptService().CheckDeptDataScope(req.DeptId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	roles := make([]int64, 0)
	for _, role := range req.RoleIds {
		roles = append(roles, *role)
	}
	err = service.NewSysRoleService().CheckRoleDataScope(roles...)
	userService := service.NewSysUserService()
	if !userService.CheckUserNameUnique(0, req.UserName) {
		response.AjaxFail(ctx, 500, "新增用户'"+*req.UserName+"'失败，登录账号已存在")
		return
	} else if xstr.IsNotEmpty(req.PhoneNumber) && !userService.CheckPhoneUnique(0, req.PhoneNumber) {
		response.AjaxFail(ctx, 500, "新增用户'"+*req.UserName+"'失败，手机号码已存在")
		return
	} else if xstr.IsNotEmpty(req.Email) && !userService.CheckEmailUnique(0, req.Email) {
		response.AjaxFail(ctx, 500, "新增用户'"+*req.UserName+"'失败，邮箱账号已存在")
		return
	}
	m, err := service.NewSysUserService().InsertUser(&req)
	if err != nil {
		response.AjaxError(ctx, err)
	} else {
		response.AjaxSuccess(ctx, m)
	}
}

// edit_user
// @Summary 编辑用户信息表
// @Description 编辑用户信息表（管理页面）
// @Tags system-user
// @Accept json
// @Produce json
// @Param req body  vo.EditSysUserReq true "req"
// @Success 200 {object} response.R[vo.EditSysUserRsp] "ok"
// @Failure 400 {string} string "bad request"
// @Failure 500 {string} string "Internal Server Error"
// @Router /system/user [put]
func edit_user(ctx *gin.Context) {
	loginUser := security.GetLoginUser()
	var req vo.EditSysUserReq
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	userService := service.NewSysUserService()
	if err := userService.CheckUserAllowed(&req.UserId); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	if err := userService.CheckUserDataScope(&req.UserId); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	if err := service.NewSysDeptService().CheckDeptDataScope(req.DeptId); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	roleIds := make([]int64, 0)
	if req.RoleIds != nil {
		for _, id := range req.RoleIds {
			roleIds = append(roleIds, *id)
		}
	}
	if err := service.NewSysRoleService().CheckRoleDataScope(roleIds...); err != nil {
		response.AjaxError(ctx, err)
		return
	}

	if !userService.CheckUserNameUnique(req.UserId, req.UserName) {
		response.AjaxFail(ctx, 500, "修改用户'"+*req.UserName+"'失败，登录账号已存在")
		return
	} else if xstr.IsNotEmpty(req.PhoneNumber) && !userService.CheckPhoneUnique(req.UserId, req.PhoneNumber) {
		response.AjaxFail(ctx, 500, "修改用户'"+*req.UserName+"'失败，手机号码已存在")
		return
	} else if xstr.IsNotEmpty(req.Email) && !userService.CheckEmailUnique(req.UserId, req.Email) {
		response.AjaxFail(ctx, 500, "修改用户'"+*req.UserName+"'失败，邮箱账号已存在")
		return
	}
	req.CreateBy = &loginUser.UserName
	m, err := service.NewSysUserService().UpdateUser(&req)
	if err != nil {
		response.AjaxFailCode(ctx, response.ServerError)
	} else {
		response.AjaxSuccess(ctx, m)
	}
}

// delete_user
// @Summary 删除用户信息表
// @Description 删除用户信息表（管理页面）
// @Tags system-user
// @Accept json
// @Produce json
// @Success 200 {object} response.R[string] "ok"
// @Failure 400 {string} string "bad request"
// @Failure 500 {string} string "Internal Server Error"
// @Router /system/user [delete]
func delete_user(ctx *gin.Context) {
	var idsStr = ctx.Param("ids")
	ids := strings.Split(idsStr, ",")
	loginUser := security.GetLoginUser()
	if loginUser == nil {
		response.AjaxFail(ctx, 403, "用户未登录")
		return
	}
	for _, id := range ids {
		if id == "1" {
			response.AjaxFail(ctx, 403, "超级管理员不允许删除")
			return
		}
		if id == fmt.Sprintf("%d", loginUser.UserId) {
			response.AjaxFail(ctx, 403, "不能删除自己")
			return
		}
	}
	err := service.NewSysUserService().DeleteUserByIds(ids)
	if err != nil {
		response.AjaxError(ctx, err)
	} else {
		response.AjaxSuccess(ctx, nil)
	}
}

func export_user(ctx *gin.Context) {
	req := vo.QuerySysUserReq{}
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	list, err := service.NewSysUserService().SelectUserList(&req, nil)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	exports := make([]*vo.SysUserExcelModel, 0)
	for _, userModel := range list.List {
		xv := &vo.SysUserExcelModel{}
		err = copier.Copy(&xv, userModel)
		if err != nil {
			continue
		}
		exports = append(exports, xv)
	}
	excel := xexcel.NewXExcel[vo.SysUserExcelModel]("用户")
	excel.Export(ctx, exports)
}

func deptTree_user(ctx *gin.Context) {
	var req vo.QuerySysDeptReq
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxFailCode(ctx, response.ParamError)
		return
	}
	response.AjaxSuccess(ctx, service.NewSysDeptService().SelectDeptTreeList(&req))
}
func auth_role_user(ctx *gin.Context) {
	var idStr = ctx.Param("id")
	userId := xnum.Str2int64(idStr)
	user := service.NewSysUserService().GetSysUser(userId)
	if user == nil {
		response.AjaxFail(ctx, 500, "该用户不存在")
		return
	}
	userModel := new(vo.SysUserModel)
	err := copier.Copy(&userModel, user)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	roles := service.NewSysRoleService().SelectRolesByUserId(userId)
	ajax := response.NewAjaxResultSuccess()
	ajax.Put("user", userModel)
	if len(roles) > 0 {
		if model.IsAdmin(&userId) {
			ajax.Put("roles", roles)
		} else {
			filters := make([]*vo.SysRoleModel, 0)
			for _, role := range roles {
				if role.RoleId != 1 {
					filters = append(filters, role)
				}
			}
			ajax.Put("roles", filters)
		}
	} else {
		ajax.Put("roles", make([]vo.SysRoleModel, 0))
	}
	response.AjaxResponse(ctx, ajax)
}

// 用户授权角色
func add_auth_role_user(ctx *gin.Context) {
	req := vo.AddAuthRoleReq{}
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	userService := service.NewSysUserService()
	err := userService.CheckUserAllowed(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.CheckUserDataScope(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.InsertUserAuth(req.UserId, req.RoleIds)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	response.AjaxSuccess(ctx, nil)
}

// 重置密码
func reset_pwd_user(ctx *gin.Context) {
	var req vo.ResetPwdSysUserReq
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	userService := service.NewSysUserService()
	err := userService.CheckUserAllowed(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.CheckUserDataScope(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.ResetPwd(&req)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	response.AjaxSuccess(ctx, nil)
}
func change_status_user(ctx *gin.Context) {
	var req vo.ChangeSysUserReq
	if err := ctx.ShouldBind(&req); err != nil {
		response.AjaxError(ctx, err)
		return
	}
	userService := service.NewSysUserService()
	err := userService.CheckUserAllowed(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.CheckUserDataScope(&req.UserId)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	err = userService.UpdateUserStatus(&req)
	if err != nil {
		response.AjaxError(ctx, err)
		return
	}
	response.AjaxSuccess(ctx, nil)
}
